import RayCastType = cc.RayCastType;
import SpriteFrame = cc.SpriteFrame;
import {colorType} from "./HeroControl";
import {colliderGroup} from "./HeroContact";
import Fluid, {fluidType} from "./Fluid";
import MirrorEndControl from "./MirrorEndControl";
import Music, {musicName} from "../PublicScript/Music";

const {ccclass, property} = cc._decorator;

// export enum laserColor{
//     red = "#FF0000",
//     blue = "#00B3FF",
//     yellow = "#BFA749",
// }
export enum laserColor{
    red ,
    blue ,
    yellow ,
    darkBlue,
}

@ccclass
export default class Ray_cast_reflection extends cc.Component {

    @property({tooltip: "射线初始射出的角度"})
    angle: number = 0;

    @property({tooltip: "射线的长度"})
    radius: number = 0;

    @property({tooltip: "射线的起始点", type: cc.Node})
    centerNode: cc.Node = null;

    @property({tooltip: "射线颜色", type: cc.Enum(laserColor)})
    color: laserColor = laserColor.yellow;

    colorList = ["#FF0000", "#2A9B8B", "#BFA749", "#1854bc"];

    onLoad () {
        this.ctx = this.node.getComponent(cc.Graphics);
        this.ctx.strokeColor = new cc.Color().fromHEX(this.colorList[this.color]);
    }

    //画线组件
    ctx = null;
    remainLength = 0;
    center = cc.v2(0,0);

    endPos = cc.v2(0,0);
    //获取现在碰到的目标节点
    endNode = null;

    start () {
        this.remainLength = this.radius;
        this.centerNode.getPosition(this.center);
        this.endPos = cc.v2(this.radius, 0).rotate(this.angle / 180 * Math.PI).add(this.center);
        this.schedule(this.rayCast, 0.01);
        // this.ray_Cast(this.center, this.endPos);
        this.radius = 200000
    }

    rayCast(){
        this.ctx.clear();
        this.remainLength = this.radius;
        this.ray_Cast(this.center, this.endPos);
    }

    protected onDestroy(): void {
        this.unschedule(this.rayCast)
    }

    //运行锁
    isEvent = false;
    pointList = [];
    //执行完毕
    executeOver = false;
    ray_Cast(pos1, pos2){
        let p1World = this.node.convertToWorldSpaceAR(pos1);                //起始点在世界坐标系下的坐标
        let p2World = this.node.convertToWorldSpaceAR(pos2);                //最长的点在世界坐标系下的坐标

        let manager = cc.director.getPhysicsManager();

        let resultList = manager.rayCast(p1World, p2World, RayCastType.AllClosest);
        //首先排除掉不能反应的刚体
        for(let i in resultList){
            if((resultList[i].collider.node.group == colliderGroup.box && resultList[i].collider.node.name == "mirrorBox") || resultList[i].collider.node.group == colliderGroup.coin){
                resultList.splice(parseInt(i), 1);
            }
        }
        // //判断谁的距离最近就使用谁
        for(let i = 0; i < resultList.length - 1; i++){
            let pos = this.node.convertToNodeSpaceAR(resultList[i].point);
            let pos2 = this.node.convertToNodeSpaceAR(resultList[i + 1].point);
            // this.ctx.circle(pos.x, pos.y, 20);
            // this.ctx.fill();
            let len1 = cc.v2(resultList[i].point.x, resultList[i].point.y)/*pos*/.sub(p1World).mag();
            let len2 = cc.v2(resultList[i + 1].point.x, resultList[i + 1].point.y)/*pos2*/.sub(p1World).mag();
            if(len1 < len2){
                resultList[i + 1] = resultList[i];
            }
        }
        let result = resultList[resultList.length - 1];

        // return;
        if(!result){
            this.ctx.moveTo(pos1.x, pos1.y);
            this.ctx.lineTo(pos2.x, pos2.y);
            this.ctx.stroke();
            return;
        }
        let pos3 = this.node.convertToNodeSpaceAR(result.point);            //发生碰撞的点
        this.ctx.moveTo(pos1.x, pos1.y);
        this.ctx.lineTo(pos3.x, pos3.y);
        this.ctx.stroke();

        //接触的时液体
        if(this.color == laserColor.blue){
            if(result.collider.node.group == colliderGroup.fluid && result.collider.tag == (fluidType.water + 1)){
                //结冰处理
                result.collider.node.getComponent(Fluid).event();
                return;
            }
        }
        if(this.color == laserColor.red){
            if(result.collider.node.group == colliderGroup.fluid && result.collider.tag == (fluidType.ice + 1)){
                //化冰处理
                result.collider.node.getComponent(Fluid).event();
                return;
            }
        }

        if(result.collider.node.group == colliderGroup.mirrorEndPoint){
            this.pointList.push(true);
        }else{
            this.pointList.push(false);
        }

        //判断是否触碰的时终点或者镜子
        if(result.collider.node.group == colliderGroup.mirrorEndPoint || result.collider.node.group != colliderGroup.mirror){
            for(let i of this.pointList){
                if(i == true){
                    this.executeOver = true;
                    break;
                }else{
                    this.executeOver = false;
                }
            }
            if(this.executeOver){
                if(!this.isEvent){
                    Music.GamePlayEffect(musicName.jiguang);
                    this.endNode = result.collider.node;
                    this.endNode.getComponent(MirrorEndControl).event(1);
                    //this.endLauncher.spriteFrame = this.launcherSprite[1];
                }
                this.isEvent = true;
            }else{
                if(this.isEvent){
                    this.endNode.getComponent(MirrorEndControl).event(-1);
                    //this.endLauncher.spriteFrame = this.launcherSprite[0];
                }
                this.isEvent = false;
            }
            this.pointList = [];
            return;
        }

        //做反射处理
        this.remainLength = this.remainLength - (pos3.sub(pos1).mag());
        // console.log(this.remainLength);

        if(this.remainLength < 1){
            return;
        }
        let pos4 = result.normal.mul(this.remainLength).add(pos3);          //剩余的长度在法向量上的点

        //判断初始线段与法向量之间的夹角
        //初始的向量
        let len_a = pos3.sub(pos1).mag();
        let len_b = pos4.sub(pos3).mag();
        let len_c = pos4.sub(pos1).mag();
        let rad = Math.acos((Math.pow(len_a,2) + Math.pow(len_b,2) - Math.pow(len_c,2))/(2*len_a*len_b));
        let pos5 = null;
        pos5 = pos4.sub(pos3).rotate(-rad).add(pos3);
        // console.log(pos5.sub(pos2).angle(pos3.sub(pos2)) * 180 /Math.PI);
        if(pos5.sub(pos2).angle(pos3.sub(pos2)) * 180 /Math.PI == 0){
            pos5 = pos4.sub(pos3).rotate(rad).add(pos3);
        }
        //开始第二次调用画线
        this.ray_Cast(pos3, pos5);
    }


    update(dt) {
       /* this.ctx.clear();
        this.remainLength = this.radius;
        this.ray_Cast(this.center, this.endPos);*/
    }
}
